<template>
  <div :class="className" :style="{ height: height, width: width }" />
</template>

<script>
import echarts from 'echarts'
import resize from './mixins/resize'
import { getGeoDatas } from "@/api/station" 

export default {
  mixins: [resize],
  props: {
    className: {
      type: String,
      default: 'chart'
    },
    width: {
      type: String,
      default: '100%'
    },
    height: {
      type: String,
      default: '100%'
    }
  },
  data() {
    return {
      chart: null,
      myZoom: 0,

      stnStates: {
        'NO': {txt: '无信息', color: '#F0FFF0'},
        'DOING': {txt: '正在作业', color:'#FF7F00'},
        'COMPLETE': {txt: '作业完毕', color:'#00FF00'},
        'WAIT': {txt: '等待作业', color:'#f4d536'},
      },

      require:{
          //需要订阅的频道放在这里
          channels: [],
          //发出申请的组件名字放在这里
          component: 'StationMap'
      },

      option: {
        legend: {
          orient: 'vertical',
          left: 'left',
          textStyle: { color: 'white' },
          data: ['无信息', '正在作业', '作业完毕', '等待作业']
        },
        geo: {
          map: 'customMap',
          roam: true,
          label: {
            emphasis: {
              show: true
            },
          },
          itemStyle: {
            normal: {
              areaColor: 'rgba(36,82,124,0.2)',
              borderColor: 'rgba(36,82,124,0.2)'
            }
          },
          emphasis: {
            itemStyle: {
              areaColor: 'rgba(36,82,124,0.2)',
              borderColor: 'rgba(36,82,124,0.2)'
            },
          },
        },
        backgroundColor: 'transparent',
        series: this.mySeries
      },

      stnPosRcvData: {},

      customMapGeoJson: {
        "type": "FeatureCollection",
        "features": [
          {
            "type": "Feature",
            "properties": {},
            "geometry": {
              "type": "Polygon",
              "coordinates": []
            }
          }
        ]
      },

      geoLineData: [],
      geoCoordMap: {},
      geoStnData: {},
      mySeries: []
    }
  },
  mounted() {
    this.$nextTick(() => {
      this.initChart()
    })
    this.getStnGeoData()
  },
  beforeDestroy() {
    for(let i = 0;i < this.require.channels.length; i++){
        this.sockets.unsubscribe(this.require.channels[i])
    }

    if (!this.chart) {
      return
    }
    this.chart.dispose()
    this.chart = null
  },

  methods: {
    initChart() {
      echarts.registerMap('customMap', this.customMapGeoJson)
      this.chart = echarts.init(this.$el, 'macarons')
      this.chart.setOption(this.option)
      this.chart.on("click", params => {
        if (params.name && params.seriesName !== '无信息') {
          // console.log('mouse click params:', params)
          this.$router.push({path: '/stationMap/index', query: {stationName: params.name}})
        }
      })

      this.chart.on('georoam', params => {
        if (params.dy || params.dx) {
          return
        }
        var _option = this.chart.getOption()

        var _zoom = _option.geo[0].zoom
        console.log(_zoom)

        if (this.myZoom === _zoom) {
          return
        }
        this.myZoom = _zoom

        var seriesStations = _option.series.filter(ele => {
          return ele.type === 'effectScatter'
        })
        var seriesLines = _option.series.filter(ele => {
          return ele.name.includes('line')
        })

        // console.log(seriesStations[0])
        // console.log(_zoom)
        _option.series = _option.series.slice(0, 0)
        seriesStations.forEach(element => {
          _option.series.push(element)
        })
        seriesLines.forEach(element => {
          _option.series.push(element)
        })
        this.chart.clear()
        this.chart.setOption(_option)
      })
    },
    initSeries() {
      const _this = this
      _this.mySeries = []
      for (let i = 0; i < _this.geoLineData.length; i++) {
        let item = _this.geoLineData[i]
        _this.mySeries.push(
          {
            name: item[0].name + ' line',
            type: 'lines',
            zlevel: 1,
            symbolSize: 5,
            lineStyle: {
              normal: {
                color: '#00FFFF',
                width: 2,
                opacity: 0.6,
                curveness: 0
              }
            },
            data: _this.convertData(item)
          }
        )
      }

      Object.keys(_this.geoStnData).forEach(key => {
        let stnName = key
        let stnData = _this.geoStnData[key]
        _this.mySeries.push(
          {
            name: stnData.state,
            type: 'effectScatter',
            coordinateSystem: 'geo',
            zlevel: 1,
            rippleEffect: {
              brushType: 'stroke'
            },
            label: {
              normal: {
                show: stnData.labelShow,
                position: 'inside',
                offset: stnData.labelOffset,
                formatter: '{b}',
                color: '#fff',
                textBorderColor: '#fff',
                textborderWidth: 2,
                textBorderType: 'solid'
              }
            },
            symbolSize: stnData.stationSize,
            itemStyle: {
              normal: {
                color: stnData.color
              },
              emphasis: {
                areaColor: '#2B91B7'
              }
            },
            data: [{
              name: stnName,
              value: _this.geoCoordMap[key].concat(0)
            }]
          }
        )
      })

      Object.keys(_this.stnStates).forEach(key => {
        _this.mySeries.push(
          {
            name: _this.stnStates[key].txt,
            type: 'effectScatter',
            coordinateSystem: 'geo',
            zlevel: 1,
            itemStyle: {
              normal: {
                color: _this.stnStates[key].color
              }
            }
          }
        )
      })
    },

    // 将指定数据转换为echarts需要的格式
    convertData(data) {
      var res = []
      var _this = this
      var dataItem = data

      var fromCoord = _this.geoCoordMap[dataItem[0].name]
      var toCoord = _this.geoCoordMap[dataItem[1].name]
      if (fromCoord && toCoord) {
        res.push({
          fromName: dataItem[0].name,
          toName: dataItem[1].name,
          coords: [fromCoord, toCoord],
          value: dataItem[1].value
        })
      }
      return res
    },

    updateChart() {
      this.updateGeoCoordMap(this.stnPosRcvData.singleStationNodes)
      this.updateGeoLineData(this.stnPosRcvData.linkRelation)
      this.updateMapRange(this.stnPosRcvData.range)
      this.initSeries()
      this.option.series = this.mySeries
      echarts.registerMap('customMap', this.customMapGeoJson)
      this.chart.setOption(this.option)
    },

    updateMapRange(ranges) {
      let leftTopPoint = ranges[0]
      let rightBottomPoint = ranges[1]
      this.customMapGeoJson.features[0].geometry.coordinates[0] = [
        [leftTopPoint.longitude, leftTopPoint.lat],
        [rightBottomPoint.longitude, leftTopPoint.lat],
        [rightBottomPoint.longitude, rightBottomPoint.lat],
        [leftTopPoint.longitude, rightBottomPoint.lat],
      ]
    },

    updateGeoCoordMap(data) {
      this.geoCoordMap = {}
      this.geoStnData = {}
      let minX = 999
      let maxX = 0
      let minY = 999
      let maxY = 0
      Object.keys(data).forEach(key => {
        let stnName = data[key].stationName
        let gnssinfo = data[key].gnssinfo
        this.geoCoordMap[stnName] = [gnssinfo.longitude, gnssinfo.lat]
        if (minX > gnssinfo.longitude) minX = gnssinfo.longitude
        if (maxX < gnssinfo.longitude) maxX = gnssinfo.longitude
        if (minY > gnssinfo.longitude) minY = gnssinfo.lat
        if (maxY < gnssinfo.longitude) maxY = gnssinfo.lat
      })
      Object.keys(data).forEach(key => {
        let stnName = data[key].stationName
        let gnssinfo = data[key].gnssinfo

        let offsetX = 33
        let offsetY = 0

        if (this.areFloatsEqual(gnssinfo.longitude, minX)) {
          offsetX = -33
          offsetY = 0
        }
        else if (this.areFloatsEqual(gnssinfo.longitude, maxX)) {
          offsetX = 33
          offsetY = 0
        }
        else if (this.areFloatsEqual(gnssinfo.lat, minY)) {
          offsetX = 0
          offsetY = -22
        }
        else if (this.areFloatsEqual(gnssinfo.lat, maxY)) {
          offsetX = 0
          offsetY = 22
        }

        let stnState = 'NO'
        this.geoStnData[stnName] = { state: this.stnStates[stnState].txt, stationSize: 10, labelShow: true, color: this.stnStates[stnState].color, labelOffset: [offsetX, offsetY] }
      })
    },

    updateStnState(data) {
      Object.keys(data).forEach(key => {
        let stnName = key
        let stnState = data[key]
        this.geoStnData[stnName].state = this.stnStates[stnState].txt
        this.geoStnData[stnName].color = this.stnStates[stnState].color
        if (this.chart) {
          this.initSeries()
          this.option.series = this.mySeries
          this.chart.setOption(this.option)
        }
      })
    },

    updateGeoLineData(data) {
      this.geoLineData = []
      Object.keys(data).forEach(key => {
        let src = key
        let dsts = data[key]
        for (let i = 0; i < dsts.length; i++) {
          this.geoLineData.push([{ name: src }, { name: dsts[i] }])
        }
      })
    },

    areFloatsEqual(a, b) {
      const epsilon = 0.001;
      return Math.abs(a - b) < epsilon;
    },

    async getStnGeoData() {
      this.stnPosRcvData = {}
      const res = await getGeoDatas()
      if (res.code === 0 && res.data) {
        this.stnPosRcvData = res.data
        this.updateChart()

        let that = this
        var geo_name='stationWorkState'
        if(!that.require.channels.includes(geo_name))
        {              
          that.require.channels.push(geo_name)    
          that.$bus.$emit('Subscribe', that.require)     
          that.sockets.subscribe(geo_name, res => {
            that.updateStnState(res.data)
          })
        }
      } 
    }
  }
}
</script>
